package com.ruoyi.htzj.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class WechatJsSdkUtil {
    private static final String APP_ID = "wx9d47fdd9b6e89cce";
    private static final String APP_SECRET = "d0ee22a57745d553e204f22c410511b7";
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
    private static String accessToken;
    private static String jsapiTicket;
    private static long accessTokenExpireTime;
    private static long jsapiTicketExpireTime;

    /**
     * 获取全局 access_token
     */
    public static synchronized String getAccessToken() throws IOException {
        long currentTime = System.currentTimeMillis();
        if (accessToken == null || currentTime > accessTokenExpireTime) {
            HttpClient httpClient = HttpClients.createDefault();
            String url = String.format(ACCESS_TOKEN_URL, APP_ID, APP_SECRET);
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = httpClient.execute(httpGet);
            String result = EntityUtils.toString(response.getEntity());
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(result, HashMap.class);
            accessToken = (String) map.get("access_token");
            int expiresIn = (int) map.get("expires_in");
            accessTokenExpireTime = currentTime + (expiresIn - 200) * 1000;
        }
        return accessToken;
    }

    /**
     * 获取 jsapi_ticket
     */
    public static synchronized String getJsapiTicket() throws IOException {
        long currentTime = System.currentTimeMillis();
        if (jsapiTicket == null || currentTime > jsapiTicketExpireTime) {
            String accessToken = getAccessToken();
            HttpClient httpClient = HttpClients.createDefault();
            String url = String.format(JSAPI_TICKET_URL, accessToken);
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = httpClient.execute(httpGet);
            String result = EntityUtils.toString(response.getEntity());
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(result, HashMap.class);
            jsapiTicket = (String) map.get("ticket");
            int expiresIn = (int) map.get("expires_in");
            jsapiTicketExpireTime = currentTime + (expiresIn - 200) * 1000;
        }
        return jsapiTicket;
    }

    /**
     * 生成签名
     */
    public static String generateSignature(String jsapiTicket, String nonceStr, String timestamp, String url) {
        String string1 = "jsapi_ticket=" + jsapiTicket +
            "&noncestr=" + nonceStr +
            "&timestamp=" + timestamp +
            "&url=" + url;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            return byteToHex(crypt.digest());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String byteToHex(final byte[] hash) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * 生成随机字符串
     */
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 生成时间戳
     */
    public static String generateTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
